package cn.com.idmy.auth.context;

import cn.com.idmy.base.config.DefaultConfig;
import cn.com.idmy.base.util.Assert;
import com.alibaba.fastjson2.JSONObject;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

public interface Request {
    @NotNull Object source();

    @NotNull String body();

    @Nullable String getNullableParam(@NotNull String name);

    default @NotNull String getParam(@NotNull String name) {
        return Assert.notBlank(getNullableParam(name), "「{}」不能为空", name);
    }

    default String getParam(@NotNull String name, String defaultValue) {
        String value = getParam(name);
        if (StrUtil.isBlank(value)) {
            return defaultValue;
        } else {
            return value;
        }
    }

    default boolean isParam(@NotNull String name, String value) {
        String paramValue = getParam(name);
        return StrUtil.isNotBlank(paramValue) && paramValue.equals(value);
    }

    default boolean hasParam(@NotNull String name) {
        return StrUtil.isNotBlank(getParam(name));
    }

    @NotNull Collection<String> paramNames();

    @NotNull JSONObject params();

    @NotNull Collection<String> headerNames();

    @NotNull Collection<String> headerValues();

    @NotNull JSONObject headers();

    @Nullable String getHeader(@NotNull String name);

    default String getHeader(@NotNull String name, String defaultValue) {
        var value = getHeader(name);
        return StrUtil.isBlank(value) ? defaultValue : value;
    }

    @Nullable String getCookieValue(@NotNull String name);

    default @NotNull String host() {
        return Assert.notBlank(getHeader("Host"), "Host 不能为空");
    }

    default @Nullable String authorization() {
        return getHeader("Authorization");
    }

    default @Nullable String origin() {
        return getHeader("Origin");
    }

    default @Nullable String userAgent() {
        return getHeader("User-Agent");
    }

    default @NotNull String contentType() {
        return Assert.notBlank(getHeader("Content-Type"), "Content-Type 不能为空");
    }

    default @Nullable String referer() {
        return getHeader("Referer");
    }

    default @Nullable String requestId() {
        return getHeader(DefaultConfig.requestIdHeaderName);
    }

    default @Nullable String spanId() {
        return getHeader(DefaultConfig.spanIdHeaderName);
    }

    default long tenantId() {
        return ConvertUtil.toLong(getHeader(DefaultConfig.tenantIdHeaderName), 0L);
    }

    default @Nullable String traceId() {
        return getHeader(DefaultConfig.traceIdHeaderName);
    }

    default @Nullable String appKey() {
        return getHeader(DefaultConfig.appKeyHeaderName);
    }

    default boolean isAjax() {
        return getHeader("X-Requested-With") != null;
    }

    @NotNull String uri();

    default boolean isPath(@NotNull String path) {
        return uri().equals(path);
    }

    @NotNull String url();

    @NotNull String method();

    @Nullable Object forward(@NotNull String path);

    @NotNull String ipv4();

    @NotNull String ipv6();
}
